home *** CD-ROM | disk | FTP | other *** search
- (*===========================================================================*)
- (* Build path array *)
- (* *)
- (* Copyright 1990, 1991, 1992 by H. Roy Engehausen. All rights reserved. *)
- (* *)
- (*===========================================================================*)
-
- {$O+}
-
- {$UNDEF DEBUG1} (* Used to debug watching BPA work *)
- {$UNDEF DEBUG2}
- {$UNDEF DEBUG3} (* Used to debug SORT *)
- {$UNDEF DEBUG4} (* Used to debug aging *)
- {$UNDEF DEBUG5} (* Used to debug size *)
- {$UNDEF DEBUG6} (* Used to debug type *)
-
- {$DEFINE POINT_CHK}
-
- UNIT BBBPA;
-
- INTERFACE
-
- USES
- bbdummy,
- bbfwdd;
-
- TYPE
- bpa_route_used_type = ^msg_r_ptr;
-
- PROCEDURE build_path_array(path_data : path_block_ptr;
- inc_routes : BOOLEAN);
-
- PROCEDURE sort_path_array(path_data : path_block_ptr);
-
- CONST path_block_mem_id : mem_id_str = 'BPA';
- CONST path_block_lst_id : mem_id_str = 'BPL';
-
- IMPLEMENTATION
-
- USES
- CRT,
- bbbug,
- bbmem,
- bbfnr,
- bbmisc3,
- bbstr,
- bbtask,
- bbtime,
- bbtrace,
- bbwin;
-
- (*===========================================================================*)
- (* Build a path data array *)
- (*===========================================================================*)
-
- PROCEDURE build_path_array(path_data : path_block_ptr;
- inc_routes : BOOLEAN);
-
- VAR
- b : BOOLEAN;
- bpa_route : bpa_route_used_type;
- e_mode : BOOLEAN;
- inx : BYTE;
- last_route : msg_r_ptr;
- msg_array : msg_p_ptr;
- msg_cnt : BYTE;
- route_used : BOOLEAN;
- out_array : msg_p_ptr;
- this_dblk : msg_d_ptr;
- this_route : msg_r_ptr;
- this_msg : msg_index_ptr;
-
- LABEL
- go_next_msg;
-
- FUNCTION test_number(s : str4) : BOOLEAN;
- VAR
- code : INTEGER;
- i : INTEGER;
-
- BEGIN;
-
- {$IFDEF DEBUG4}
- WRITELN('#1=', LENGTH(s), '=', s);
- {$ENDIF}
-
- test_number := FALSE;
- IF (LENGTH(s) > 3) OR (s = '') THEN EXIT;
-
- VAL(s, i, code);
-
- {$IFDEF DEBUG4}
- WRITELN('#2=', i, '=', code);
- {$ENDIF}
-
- IF (code <> 0) OR (i < 0) THEN EXIT;
- test_number := TRUE;
-
- END;
-
- BEGIN;
-
- {$IFDEF DEBUG1}
- WRITELN('BPA look - ',
- path_data^.path_pattern, ' / ', path_data^.path_target);
- {$ENDIF}
-
- {$IFDEF DEBUG6}
- WRITELN('BPA type - ', LENGTH(path_data^.path_type_send), ' - ',
- path_data^.path_type_send);
- {$ENDIF}
-
- (*-----------------------------------------------------------------------*)
- (* Initialize things *)
- (*-----------------------------------------------------------------------*)
-
- msg_cnt := 0;
- last_route := NIL;
- path_data^.path_route := NIL;
-
- (*-----------------------------------------------------------------------*)
- (* Are we in emergency forward only mode? *)
- (*-----------------------------------------------------------------------*)
-
- e_mode := opt_block.operate_mode.mode_fwd_emer
- AND active_port^.port_operate_mode.mode_fwd_emer;
-
- (*-----------------------------------------------------------------------*)
- (* Free any old area; *)
- (*-----------------------------------------------------------------------*)
-
- free_task_mem(path_block_mem_id, TRUE);
- free_task_mem(path_block_lst_id, TRUE);
-
- (*-----------------------------------------------------------------------*)
- (* Search down the route list *)
- (*-----------------------------------------------------------------------*)
-
- this_route := find_next_route(path_data, @msg_route_list);
-
- (*-----------------------------------------------------------------------*)
- (* Get the array area *)
- (*-----------------------------------------------------------------------*)
-
- IF this_route <> NIL THEN
- msg_array := get_task_mem(path_block_mem_id, SIZEOF(msg_path_block));
-
- IF (this_route = NIL) OR (msg_array = NIL) THEN
- BEGIN;
- path_data^.path_msg_count := 0;
- path_data^.path_msg_list := NIL;
- {$IFDEF DEBUG1}
- WRITELN('BPA not found');
- {$ENDIF}
- EXIT;
- END;
-
- (*-----------------------------------------------------------------------*)
- (* Loop while we found something *)
- (*-----------------------------------------------------------------------*)
-
- {$IFDEF DEBUG1}
- WRITELN('BPA found - ',
- path_data^.path_pattern, ' / ', path_data^.path_target);
- {$ENDIF}
-
- WHILE this_route <> NIL DO
- BEGIN;
-
- (*-------------------------------------------------------------------*)
- (* Debugging *)
- (*-------------------------------------------------------------------*)
-
- {$IFDEF POINT_CHK}
- test_pointer(this_route);
- {$ENDIF}
-
- {$IFDEF DEBUG1}
- WRITELN('BPA route found -- ', this_route^.msg_r_info);
- {$ENDIF}
-
- (*-------------------------------------------------------------------*)
- (* Assume route not used *)
- (*-------------------------------------------------------------------*)
-
- route_used := FALSE;
-
- (*-------------------------------------------------------------------*)
- (* Search the message list looking for messages pointing at this *)
- (* route *)
- (*-------------------------------------------------------------------*)
-
- this_msg := find_next_msg(this_route, NIL, inx);
-
- WHILE (this_msg <> NIL) AND (msg_cnt < msg_path_max_msgs) DO
- BEGIN;
-
- {$IFDEF POINT_CHK}
- test_pointer(this_msg);
- {$ENDIF}
-
- {$IFDEF DEBUG1}
- WRITELN('BPA msg found -- ', this_msg^.msg_i_mb.msg_number);
- {$ENDIF}
-
- (*---------------------------------------------------------------*)
- (* See if we can forward this message type *)
- (*---------------------------------------------------------------*)
-
- b := (NOT e_mode) OR (this_msg^.msg_i_mb.msg_type >= mt_nts);
-
- IF b AND (path_data^.path_type_send <> '') THEN
- b := POS(this_msg^.msg_i_mb.msg_type,
- path_data^.path_type_send) > 0;
-
- IF NOT b THEN
- BEGIN;
- path_data^.path_type_rej := TRUE;
- GOTO go_next_msg;
- END;
-
- (*---------------------------------------------------------------*)
- (* See if size is ok *)
- (*---------------------------------------------------------------*)
-
- IF this_msg^.msg_i_mb.msg_size > path_data^.path_size THEN
- BEGIN;
- path_data^.path_size_rej := TRUE;
- GOTO go_next_msg;
- END;
-
- (*---------------------------------------------------------------*)
- (* See if age is ok *)
- (*---------------------------------------------------------------*)
-
- IF this_msg^.msg_i_mb.msg_dt_in >= path_data^.path_age THEN
- BEGIN;
- path_data^.path_date_rej := TRUE;
- GOTO go_next_msg;
- END;
-
- (*---------------------------------------------------------------*)
- (* We found one so stick it in the array *)
- (*---------------------------------------------------------------*)
-
- INC(msg_cnt);
-
- msg_array^[msg_cnt].msg_p_i := this_msg;
- msg_array^[msg_cnt].msg_p_item := inx;
-
- (*---------------------------------------------------------------*)
- (* Come here to skip this message *)
- (*---------------------------------------------------------------*)
-
- go_next_msg:
-
- (*---------------------------------------------------------------*)
- (* Show route was used *)
- (*---------------------------------------------------------------*)
-
- route_used := TRUE;
-
- (*---------------------------------------------------------------*)
- (* Find next message *)
- (*---------------------------------------------------------------*)
-
- this_msg := find_next_msg(this_route, this_msg, inx);
-
- END; (*----- End loop thru all messages ---------------------------*)
-
- (*-------------------------------------------------------------------*)
- (* Bump route # used if necessary *)
- (*-------------------------------------------------------------------*)
-
- IF inc_routes AND route_used THEN
- REPEAT
- INC(this_route^.msg_r_nroute);
- UNTIL NOT test_number(subword(@this_route^.msg_r_info,
- this_route^.msg_r_nroute, 1));
-
- (*-------------------------------------------------------------------*)
- (* See if route was used. *)
- (*-------------------------------------------------------------------*)
-
- IF route_used THEN
- BEGIN;
-
- (*---------------------------------------------------------------*)
- (* Route used so save the info *)
- (*---------------------------------------------------------------*)
-
- bpa_route := get_task_mem(path_block_lst_id,
- SIZEOF(bpa_route_used_type));
-
- {$IFDEF POINT_CHK}
- test_pointer(bpa_route);
- {$ENDIF}
-
- bpa_route^ := this_route;
-
- path_data^.path_r_nochange := FALSE;
-
- END;
-
- (*-------------------------------------------------------------------*)
- (* Go to next route *)
- (*-------------------------------------------------------------------*)
-
- this_route := find_next_route(path_data, this_route);
-
- END; (*---- End loop thru all routes ----------------------------------*)
-
- (*-----------------------------------------------------------------------*)
- (* Reduce debugging pain *)
- (*-----------------------------------------------------------------------*)
-
- {$IFDEF POINT_CHK}
- task_switch;
- {$ENDIF}
-
- (*-----------------------------------------------------------------------*)
- (* Set the pointers to the output. Free unused part of array. If *)
- (* no messages, free the whole shebang *)
- (*-----------------------------------------------------------------------*)
-
- path_data^.path_msg_count := msg_cnt;
-
- IF msg_cnt = 0 THEN
- BEGIN
-
- path_data^.path_msg_list := NIL;
- free_task_mem(path_block_mem_id, TRUE);
-
- END
- ELSE
- BEGIN;
-
- path_data^.path_msg_list := msg_array;
-
- msg_cnt := msg_path_max_msgs - msg_cnt;
-
- IF msg_cnt > 0 THEN
- free_task_mem_end(path_block_mem_id,
- WORD(msg_cnt) * SIZEOF(msg_path_array_item));
-
- END;
-
- {$IFDEF DEBUG2}
- WRITELN('BPA done -- ', path_data^.path_msg_count,
- ' -- ', p2x(path_data^.path_msg_list));
- {$ENDIF}
-
- END;
-
- (*===========================================================================*)
- (* Sort a path data array *)
- (*===========================================================================*)
-
- PROCEDURE sort_path_array(path_data : path_block_ptr);
-
- VAR
- inx : BYTE;
- msg_cnt : BYTE;
- msg_array : msg_p_ptr;
- sort_type : CHAR;
-
- (*=========================================================================*)
- (* Procedure to do one sort *)
- (*=========================================================================*)
-
- PROCEDURE sort_bpa(sort_type : CHAR; msg_array : msg_p_ptr);
-
- VAR
- show_err : BOOLEAN;
- need_pass : BOOLEAN;
- p1 : msg_path_array_item;
- p2 : msg_path_array_item;
- sort_inx : BYTE;
- sort_max : BYTE;
-
- {$IFDEF DEBUG3}
- s1 : STRING;
- s2 : STRING[5];
- {$ENDIF}
-
- (*=======================================================================*)
- (* Compare two items. If compare is TRUE then they are out of order *)
- (*=======================================================================*)
-
- FUNCTION sort_compare(m1, m2 : msg_index_ptr): BOOLEAN;
-
- VAR
- d1 : LONGINT;
- d2 : LONGINT;
- i : INTEGER;
-
- BEGIN;
-
- (*-------------------------------------------------------------------*)
- (* Execute the correct sort *)
- (*-------------------------------------------------------------------*)
-
- CASE sort_type OF
-
- (*-----------------------------------------------------------------*)
- (* Sort by type *)
- (*-----------------------------------------------------------------*)
-
- path_sort_type:
- BEGIN;
- i := ORD(m1^.msg_i_mb.msg_type) - ORD(m2^.msg_i_mb.msg_type);
- IF i <> 0 THEN
- sort_compare := i < 0
- ELSE
- sort_compare := (m1^.msg_i_mb.msg_flag AND mf_fwd_list) >
- (m2^.msg_i_mb.msg_flag AND mf_fwd_list);
- END;
-
- (*-----------------------------------------------------------------*)
- (* Sort by age *)
- (*-----------------------------------------------------------------*)
-
- path_sort_age:
- sort_compare := m1^.msg_i_mb.msg_dt_in > m2^.msg_i_mb.msg_dt_in;
-
- (*-----------------------------------------------------------------*)
- (* Sort by size *)
- (*-----------------------------------------------------------------*)
-
- path_sort_size:
- sort_compare := m1^.msg_i_mb.msg_size > m2^.msg_i_mb.msg_size;
-
- (*-----------------------------------------------------------------*)
- (* Sort by date (Time doesnt' count) *)
- (*-----------------------------------------------------------------*)
-
- path_sort_date, path_sort_rdate:
- BEGIN;
- d1 := m1^.msg_i_mb.msg_dt_in DIV ticks_per_day;
- d2 := m2^.msg_i_mb.msg_dt_in DIV ticks_per_day;
- IF sort_type = path_sort_date THEN
- sort_compare := d1 > d2
- ELSE
- sort_compare := d1 < d2;
- END;
-
- (*-----------------------------------------------------------------*)
- (* Bad sort type *)
- (*-----------------------------------------------------------------*)
-
- ELSE
- BEGIN;
- IF show_err THEN
- BEGIN;
- window_write_critical('FWD:Bad sort character -- ',
- sort_type);
- show_err := FALSE;
- END;
- sort_compare := FALSE;
- END;
-
- END;
-
- END; (*----- End sort compare subroutine ------------------------------*)
-
- (*-----------------------------------------------------------------------*)
- (* Main line of sort once *)
- (*-----------------------------------------------------------------------*)
-
- BEGIN;
-
- (*---------------------------------------------------------------------*)
- (* Get ready to loop *)
- (*---------------------------------------------------------------------*)
-
- show_err := TRUE;
- sort_max := msg_cnt - 1;
-
- {$IFDEF DEBUG3}
- WRITELN('Sorting ', sort_max, ' by ', sort_type);
- {$ENDIF}
-
- (*---------------------------------------------------------------------*)
- (* Keep looping until no more sorting to be done *)
- (*---------------------------------------------------------------------*)
-
- REPEAT
-
- {$IFDEF DEBUG3}
- WRITELN('Sort pass');
- {$ENDIF}
-
- need_pass := FALSE;
-
- (*-------------------------------------------------------------------*)
- (* Make a pass over the array to sort it *)
- (*-------------------------------------------------------------------*)
-
- FOR sort_inx := 1 TO sort_max DO
- BEGIN;
-
- p1 := msg_array^[sort_inx];
- p2 := msg_array^[sort_inx + 1];
-
- IF sort_compare(p1.msg_p_i, p2.msg_p_i) THEN
- BEGIN;
- msg_array^[sort_inx] := p2;
- msg_array^[sort_inx + 1] := p1;
- need_pass := TRUE;
- END;
-
- END;
-
- UNTIL NOT need_pass; (*---- End sort loop -----------------------------*)
-
- (*---------------------------------------------------------------------*)
- (* Debugging display of SORT results *)
- (*---------------------------------------------------------------------*)
-
- {$IFDEF DEBUG3}
- WRITELN('Sort out');
- s1 := '';
- FOR sort_inx := 1 TO (sort_max + 1) DO
- BEGIN;
- STR(msg_array^[sort_inx].msg_p_i^.msg_i_mb.msg_number, s2);
- s1 := s1 + s2;
- IF LENGTH(s1) > 70 THEN
- BEGIN;
- WRITELN(s1);
- s1 := '';
- END
- ELSE
- s1 := s1 + ', ';
- END;
- IF LENGTH(s1) > 0 THEN
- WRITELN(s1);
-
- WRITELN('Sort out');
- DELAY(3000);
- {$ENDIF}
-
- END; (*----- End actual sort subroutine ---------------------------------*)
-
- (*-------------------------------------------------------------------------*)
- (* Main line of sort path array *)
- (*-------------------------------------------------------------------------*)
-
- BEGIN;
-
- (*-----------------------------------------------------------------------*)
- (* Initialize things. Leave if nothing to do *)
- (*-----------------------------------------------------------------------*)
-
- msg_cnt := path_data^.path_msg_count;
-
- IF (msg_cnt < 2) THEN
- EXIT;
-
- msg_array := path_data^.path_msg_list;
-
- (*-----------------------------------------------------------------------*)
- (* Sort the array *)
- (*-----------------------------------------------------------------------*)
-
- FOR inx := SIZEOF(path_data^.path_sort) DOWNTO 1 DO
- BEGIN;
- sort_type := path_data^.path_sort[inx];
- {$IFDEF DEBUG3}
- WRITELN('SORT TYPE = ', sort_type, ' / ', inx);
- {$ENDIF}
- IF sort_type <> path_sort_none THEN
- BEGIN;
- sort_bpa(sort_type, msg_array);
- task_switch;
- END;
- END;
-
- END; (*----- End sort array -----------------------------------------------*)
-
- END.